package com.museum.config;

import com.museum.security.*;
import com.museum.utils.JwtUtil;
import com.museum.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;



/**
 * @author Akihi
 * @create 2022/11/13
 */
@Configuration
public class SecurityConfig {
    @Autowired
    JwtUtil jwtUtil;
    @Autowired
    RedisUtil redisUtil;
    /*白名单*/
    public static final String[] URL_WHITELIST = {
            /*"/webjars/**",*/
            "/favicon.ico",
            "/captcha",
            "/login",
            /*"/test/**"*/
    };
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        LoginFailureHandler loginFailureHandler = new LoginFailureHandler();

        http.cors().and().csrf().disable()
                // 登录配置
                .formLogin()   //表单提交方式
                .successHandler(new LoginSuccessHandler(jwtUtil))   //配置登录成功处理器
                .failureHandler(loginFailureHandler) //配置登录失败处理器
                //登出配置
                .and()
                .logout()
                .logoutSuccessHandler(new JwtLogoutSuccessHandler(jwtUtil))
                // 配置拦截规则
                .and()
                .authorizeRequests()
                .antMatchers(URL_WHITELIST).permitAll() //白名单
                .anyRequest().authenticated()
                // 禁用session
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                // 异常处理器
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(new JwtAuthenticationEntryPoint())
                // 配置自定义的过滤器(配置验证码过滤器在身份校验过滤器之前)
                .and()
                .addFilter(
                        new JwtAuthenticationFilter(authenticationManager
                                (http.getSharedObject(AuthenticationConfiguration.class)),
                                jwtUtil
                        )
                )
                .addFilterBefore(new CaptchaFilter(redisUtil, loginFailureHandler), UsernamePasswordAuthenticationFilter.class) // 登录验证码校验过滤器
        ;
        return http.build();
    }

    /*全局公开身份验证管理器*/
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
            throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    //使用Security内置的加密和验证策略
    @Bean
    BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
    /*配置WebSecurity对象*/
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        /*使验证码的url不走过滤器链*/
        return (webSecurity) -> webSecurity.ignoring().antMatchers("/captcha");
    }
}
